﻿#pragma once

#include "stdafx.h"
#include <string.h>
#include<vector>
#include<map>
#include<algorithm>
#include"Struct.h"
#include<fstream> 
#include"afx.h"
#include"MD5.h"
#include "Shellapi.h"
#include<algorithm>
#include<boost\regex.hpp>
#include "util.h"
#include <io.h>
using namespace std;

bool isNum(string str) {
	boost::regex num("[0-9]+");
	if (boost::regex_match(str, num)) {
		return true;
	}
	return false;
	
}

void backup() {
	//备份
		//弹出一个选择文件夹的对话框
	TCHAR           szFolderPath[MAX_PATH] = { 0 };
	CString         strFolderPath = TEXT("");
	BROWSEINFO      sInfo;
	::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
	sInfo.pidlRoot = 0;
	sInfo.lpszTitle = _T("请选择一个文件夹：");
	sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
	sInfo.lpfn = NULL;
	// 显示文件夹选择对话框  
	LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
	if (lpidlBrowse != NULL) //点了"确定"按钮
	{
		// 取得文件夹名  
		if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath)) {
			//获得系统时间 
			CTime currTime;
			currTime = CTime::GetCurrentTime();
			CString strTime;
			strTime.Format(_T("%.4d-%.2d-%.2d-%.2d-%.2d-%.2d"),
				currTime.GetYear(), currTime.GetMonth(), currTime.GetDay(), currTime.GetHour(), currTime.GetMinute(), currTime.GetSecond());
			//把文件夹复制到制定路径下
			strFolderPath = szFolderPath;
			CString str;
			str = strFolderPath + _T("\\") + strTime;
			//把备份的文件路径保存到文件中
			CStdioFile file;
			CString fileName = _T("backup.txt");
			file.Open(fileName, CFile::modeCreate | CFile::modeWrite);
			file.WriteString(str + L"\\data");
			CreateDirectory(str, NULL);
			str.Append(_T('\0'));
			SHFILEOPSTRUCT fop;
			fop.wFunc = FO_COPY;//选择执行类型
			fop.pFrom = _T("data\\");//原文件夹的路径
			fop.pTo = str;//拷入文件的文件夹路径
			fop.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
			SHFileOperation(&fop);
			AfxMessageBox(_T("文件夹备份成功"));
			file.Close();
		}
	}
	if (lpidlBrowse != NULL) {
		::CoTaskMemFree(lpidlBrowse);
	}
}

void Restore() {
	if (!FileExist("backup.txt")) {
		AfxMessageBox(L"您还没有备份文件！");
		return;
	}
	//还原
	CStdioFile file(_T("backup.txt"), CFile::modeRead);
	CString strPath = TEXT("");
	TCHAR szPath[MAX_PATH] = _T("");
	file.ReadString(strPath);
	strPath.Append(_T('\0'));
	lstrcpy(szPath, strPath);
	SHFILEOPSTRUCT fop;
	fop.wFunc = FO_COPY;//选择执行类型
	fop.pFrom = szPath;//原文件夹的路径
	fop.pTo = _T(".\\");//拷入文件的文件夹路径
	fop.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
	SHFileOperation(&fop);
	AfxMessageBox(_T("文件夹还原成功"));
	file.Close();
}


string CStringTostring(CString data) {
	int n = 0;
	//通过将宽字节转换成多字节来获得多字节的位数
	n = WideCharToMultiByte(CP_OEMCP, 0, data, -1, NULL, 0, 0, FALSE);
	char* pBuff = new char[n];
	//初始化数组
	memset(pBuff, 0, n);
	//将宽字节转换成多字节
	WideCharToMultiByte(CP_OEMCP, 0, data.GetBuffer(0), n, pBuff, n, 0, FALSE);
	string str = pBuff;
	delete pBuff;
	return str;
}
/*用户密码加密
*@TODO
*/
string  Password(string pwd) {
	return md5(pwd + "DBMS");
}

//记录日志的函数
/*
*  @filePath  日志文件完整路径
 * @ content 要写入的内容
 */
void MyLogger(string filePath, string content) {
	ofstream outfile;
	CFileStatus filestatus;
	CString str;
	filePath += ".log";
	str = filePath.c_str();
	if (!CFile::GetStatus(str, filestatus)) {
		CFile f;
		f.Open(str, CFile::modeCreate);
		f.Close();
	}

	outfile.open(filePath, ios::app);
	outfile << "  " << content.c_str();
	outfile.close();
}

//给char数组赋值
void Conversion(char *arr, char* p) {
	for (unsigned int i = 0; i < strlen(p); i++) {
		arr[i] = p[i];
	}
	arr[strlen(p)] = '\0';
}
//给char数组赋值
void Conversion(char *arr, const char* p) {
	for (unsigned int i = 0; i < strlen(p); i++) {
		arr[i] = p[i];
	}
	arr[strlen(p)] = '\0';
}

//删除目录及其下面的文件
void DeleteDirectory(CString strDir) {
	if (strDir.IsEmpty())
	{
		RemoveDirectory(strDir);
		return;
	}
	//首先删除文件及子文件夹 
	CFileFind   ff;
	BOOL bFound = ff.FindFile(strDir + _T("\\*"), 0);
	while (bFound)
	{
		bFound = ff.FindNextFile();
		if (ff.GetFileName() == _T(".") || ff.GetFileName() == _T(".."))
			continue;
		//去掉文件(夹)只读等属性 
		SetFileAttributes(ff.GetFilePath(), FILE_ATTRIBUTE_NORMAL);
		if (ff.IsDirectory()) {
			//递归删除子文件夹
			DeleteDirectory(ff.GetFilePath());
			RemoveDirectory(ff.GetFilePath());
		}
		else {
			DeleteFile(ff.GetFilePath());   //删除文件 
		}
	}
	ff.Close();
	//然后删除该文件夹 
	RemoveDirectory(strDir);
}

//
char* SimpleMap(char *s) {
	if (strcmp(s, "1") == 0)
		return "int";
	if (strcmp(s, "2") == 0)
		return "bool";
	if (strcmp(s, "3") == 0)
		return "double";

	if (strcmp(s, "5") == 0)
		return "datetime";
	if (strcmp(s, "6") == 0)
		return "primary key";
	if (strcmp(s, "7") == 0)
		return "unique";
	if (strcmp(s, "8") == 0)
		return "not null";
	if (strcmp(s, "9") == 0)
		return "auto_increase";
	return s;
}

bool IsTable(CString path, const char* tname) {
	CFile tfile;
	tfile.Open(path, CFile::modeReadWrite | CFile::typeBinary, NULL);
	Table_Tb tb; bool index = false;
	while (tfile.Read(&tb, 1176) != 0)
		if (strcmp(tb.name, tname) == 0)
			index = true;
	tfile.Close();
	return index;
}

bool IsTable(string path, const char* tname) {
	CString tpath;
	tpath = path.c_str();
	CFile tfile;
	tfile.Open(tpath, CFile::modeReadWrite | CFile::typeBinary, NULL);
	Table_Tb tb; bool index = false;
	while (tfile.Read(&tb, 1176) != 0)
		if (strcmp(tb.name, tname) == 0)
			index = true;
	tfile.Close();
	return index;
}

char* GetTime(char*time) {
	int Y, M, D, h, m, s;
	CTime t;
	sscanf(time, "%d-%d-%d %d:%d:%d", &Y, &M, &D, &h, &m, &s);
	t = CTime(Y, M, D, h, m, s);
	return time;
}

bool IsDateValid(const char *DateString)
{
	string temp;
	bool bLeapYear;
	int nYear=0, nMonth=0, nDay=0;
	temp = DateString;
	vector<string>vec = split(temp, "-");
	if (vec.size() < 3)
		return false;
	nYear = stoi(vec[0]);
	nMonth = stoi(vec[1]);
	nDay = stoi(vec[2]);

	map<int, int> mpMonDay;
	mpMonDay[1] = 31;
	mpMonDay[2] = 28;
	mpMonDay[3] = 31;
	mpMonDay[4] = 30;
	mpMonDay[5] = 31;
	mpMonDay[6] = 30;
	mpMonDay[7] = 31;
	mpMonDay[8] = 31;
	mpMonDay[9] = 30;
	mpMonDay[10] = 31;
	mpMonDay[11] = 30;
	mpMonDay[12] = 31;

	if ((nYear < 1900) || (nMonth < 1) || (nMonth > 12) || (nDay < 1) || (nDay > 31))
		return false;

	bLeapYear = false;
	if ((nYear % 4 == 0) && (nYear % 100 != 0))
		bLeapYear = true;
	else if (nYear % 400 == 0)
		bLeapYear = true;

	if (bLeapYear)
		mpMonDay[2] = 29;
	else
		mpMonDay[2] = 28;

	if (nDay > mpMonDay[nMonth])
		return false;

	return true;
}

vector<string>split(string str, string token) {
	vector<string>result; int pos = 0;
	while ((pos = str.find(token)) != -1) {
		result.push_back(str.substr(0, pos));
		str = str.substr(pos + token.length(), str.length() - pos - token.length());
	}
	result.push_back(str);
	return result;
}

string isType(string str, string &param) {
	if (str == "int") {
		param = "4";
		return "1";
	}
	if (str == "bool") {
		param = "1";
		return "2";
	}
	if (str == "datetime") {
		param = "8";
		return "5";
	}
	if (str == "double") {
		param = "8";
		return "3";
	}

	string var = "varchar\\(\\d+\\)";
	boost::regex varchar(var);
	if (boost::regex_match(str, varchar)) {
		boost::regex re("(?<=\\().+(?=\\))");
		boost::smatch csm;
		if (boost::regex_search(str, csm, re)) {
			param = csm.str();
		}
		return "4";
	}
	return "-1";
}

string trimAll(string str, string replace) {
	int begin = 0;
	begin = str.find(replace, begin);
	while (begin != -1)
	{
		str.replace(begin, replace.length(), "");
		begin = str.find(" ", begin);
	}
	return str;
}
string trim(string s, string token)
{
	if (!s.empty())
	{
		s.erase(0, s.find_first_not_of(token));
		s.erase(s.find_last_not_of(token) + 1);
	}
	return s;
}

bool IsUnique(CString path, char * type, int pos, int lenth, int size, string value)
{
	CFile file;
	file.Open(path, CFile::modeRead | CFile::typeBinary, NULL);
	string strType = type;
	if (strType == "1") {
		int temp = 0;
		file.Seek(pos, file.begin);
		while (file.Read(&temp, 4) != 0) {
			if (temp == stoi(value)) {
				file.Close();
				return false;
			}
			pos += lenth;
			file.Seek(pos, file.begin);
		}
	}
	else if (strType == "2") {
		int temp = 0;
		file.Seek(pos, file.begin);
		while (file.Read(&temp, size) != 0) {
			if (temp == stoi(value)) {
				file.Close();
				return false;
			}
			pos += lenth;
			file.Seek(pos, file.begin);
		}
	}
	else if (strType == "3") {
		double temp = false;
		file.Seek(pos, file.begin);
		while (file.Read(&temp, size) != 0) {
			double dvalue = stod(value);
			if (temp == dvalue) {
				file.Close();
				return false;
			}
			pos += lenth;
			file.Seek(pos, file.begin);
		}
	}
	else if (strType == "4") {
		char* temp = new char[size + 1];
		memset(temp, 0, size + 1);
		file.Seek(pos, file.begin);
		while (file.Read(temp, size) != 0) {
			if (strcmp(temp, value.c_str()) == 0) {
				file.Close();
				delete temp;
				return false;
			}
			pos += lenth;
			file.Seek(pos, file.begin);
		}
		delete temp;
	}
	else if (strType == "5") {
		unsigned long temp = 0;
		int nYear, nMonth, nDate, nHour = 0, nMin = 0, nSec = 0;
		sscanf(value.c_str(), "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
		CTime t(nYear, nMonth, nDate, nHour, nMin, nSec);
		unsigned long timeValue = (unsigned long)t.GetTime();
		file.Seek(pos, file.begin);
		while (file.Read(&temp, sizeof(temp)) != 0) {
			if (temp == timeValue) {
				file.Close();
				return false;
			}
			pos += lenth;
			file.Seek(pos, file.begin);
		}
	}
	file.Close();
	return true;
}

//比较where
bool JudegWhere(CFile &file, int offset, struct_where& wh) {
	file.Seek(offset, file.begin);
	bool result = false;
	string type = wh.type;
	if (type == "1") {
		int value = stoi(wh.value);
		int temp = 0;
		file.Read(&temp, sizeof(int));
		if (wh.operater == "=")
			result = (temp == value);
		else if (wh.operater == ">")
			result = (temp > value);
		else if (wh.operater == "<")
			result = (temp < value);

	}
	else if (type == "2") {
		bool value = false;
		if (wh.value == "true")
			value = true;
		bool temp = false;
		file.Read(&temp, sizeof(bool));
		if (wh.operater == "=")
			result = (temp == value);
		else if (wh.operater == ">")
			result = (temp > value);
		else if (wh.operater == "<")
			result = (temp < value);
	}
	else if (type == "3") {
		double value = stod(wh.value);
		double temp = 0;
		file.Read(&temp, sizeof(double));
		if (wh.operater == "=")
			result = (temp == value);
		else if (wh.operater == ">")
			result = (temp > value);
		else if (wh.operater == "<")
			result = (temp < value);
	}
	else if (type == "4") {
		char temp[256] = { 0 };
		file.Read(temp, wh.size);
		string t = temp;
		if (wh.operater == "=")
			result = (temp == wh.value);
		else if (wh.operater == ">")
			result = (temp > wh.value);
		else if (wh.operater == "<")
			result = (temp < wh.value);
	}
	else {
		//时间类型，之后在说。
		unsigned long temp = 0;
		file.Read(&temp, sizeof(temp));
		int nYear, nMonth, nDate, nHour = 0, nMin = 0, nSec = 0;
		sscanf(wh.value.c_str(), "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
		CTime t(nYear, nMonth, nDate, nHour, nMin, nSec);
		unsigned long timeValue = (unsigned long)t.GetTime();

		if (wh.operater == "=")
			result = (temp == timeValue);
		else if (wh.operater == ">")
			result = (temp > timeValue);
		else if (wh.operater == "<")
			result = (temp < timeValue);
	}
	return result;
}

//int GetSize(string str) {
//	if (str == "1") 
//		return 4;
//	
//	if (str == "2") 
//		return 1;
//	if (str == "5"||str=="3") 
//		return 8;
//	
//	if (str == "4")
//		return 256;
//}
bool FileExist(const char *filename)
{
	return (_access(filename, 0) == 0);
}

